<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue3 Gridstack</title>
    <link rel="stylesheet" href="demo.css"/>
    <script src="../dist/gridstack-all.js"></script>
  </head>
  <body>
    <main id="app">
      <h1>How to integrate GridStack.js with Vue.js</h1>
      <p>
        As with any virtual DOM based framework, you need to check if Vue has
        rendered the DOM (or any updates to it) <strong>before</strong> you
        initialize GridStack or call its methods. As a basic example, check this
        component's <code>mounted</code> hook.
      </p>
      <p>
        If your app requires more complex render logic than the inline template
        in `addWidget`, consider
        <a
          href="https://github.com/gridstack/gridstack.js/tree/master/doc#makewidgetel"
          >makeWidget</a
        >
        to let Vue deal with DOM rendering.
      </p>
      <button type="button" @click="addNewWidget()">Add Widget</button> {{ info }}
      <div class="grid-stack"></div>
    </main>
    <script type="module">
      import { createApp, ref, onMounted } from "https://cdn.jsdelivr.net/npm/vue@3.0.11/dist/vue.esm-browser.js";

      createApp({
        setup() {
          let count = ref(0);
          let info = ref("");
          let grid = null; // DO NOT use ref(null) as proxies GS will break all logic when comparing structures... see https://github.com/gridstack/gridstack.js/issues/2115
          const items = [
            { x: 2, y: 1, h: 2 },
            { x: 2, y: 4, w: 3 },
            { x: 4, y: 2 },
            { x: 3, y: 1, h: 2 },
            { x: 0, y: 6, w: 2, h: 2 },
          ];

          onMounted(() => {
            grid = GridStack.init({ // DO NOT use grid.value = GridStack.init(), see above
              float: true,
              cellHeight: "70px",
              minRow: 1,
            });

            grid.on("dragstop", function (event, element) {
              const node = element.gridstackNode;
              info.value = `you just dragged node #${node.id} to ${node.x},${node.y} – good job!`;
            });
          });

          function addNewWidget() {
            const node = items[count.value] || {
              x: Math.round(12 * Math.random()),
              y: Math.round(5 * Math.random()),
              w: Math.round(1 + 3 * Math.random()),
              h: Math.round(1 + 3 * Math.random()),
            };
            node.id = node.content = String(count.value++);
            grid.addWidget(node);
          }

          return {
            info,
            addNewWidget,
          };
        },

        watch: {
          /**
           * Clear the info text after a two second timeout. Clears previous timeout first.
           */
          info: function (newVal) {
            if (newVal.length === 0) return;

            window.clearTimeout(this.timerId);
            this.timerId = window.setTimeout(() => {
              this.info = "";
            }, 2000);
          },
        },
      }).mount("#app");
    </script>
  </body>
</html>
